document.addEventListener('DOMContentLoaded', () => {

  // --- Configuration ---
  const API_BASE_URL = '/api'; // Adjust if your API files are elsewhere
  const ENTITY_CONFIG = {
      'user': { endpoint: 'users.php', idField: 'UserID', formId: 'add-user-form', tableBodyId: 'user-table-body', primaryKey: 'UserID', nameField: 'Username' },
      'student': { endpoint: 'students.php', idField: 'StudentID', formId: 'add-student-form', tableBodyId: 'student-table-body', primaryKey: 'StudentID', nameField: 'Name' },
      'teacher': { endpoint: 'teachers.php', idField: 'TeacherID', formId: 'add-teacher-form', tableBodyId: 'teacher-table-body', primaryKey: 'TeacherID', nameField: 'Name' },
      'department': { endpoint: 'departments.php', idField: 'DepartmentID', formId: 'add-department-form', tableBodyId: 'department-table-body', primaryKey: 'DepartmentID', nameField: 'DepartmentName' },
      'course': { endpoint: 'courses.php', idField: 'CourseID', formId: 'add-course-form', tableBodyId: 'course-table-body', primaryKey: 'CourseID', nameField: 'CourseName' },
      'course-offering': { endpoint: 'courseofferings.php', idField: 'OfferingID', formId: 'add-offering-form', tableBodyId: 'offering-table-body', primaryKey: 'OfferingID', nameField: 'OfferingID' /* No simple name, use ID */ }
      // Add 'enrollment' if needed
  };

  // Global storage for fetched data used in dropdowns
  let departmentsData = [];
  let coursesData = [];
  let teachersData = [];

  // --- UI Elements ---
  const sidebarMenuItems = document.querySelectorAll('.sidebar-menu li');
  const tabContents = document.querySelectorAll('.tab-content');
  const addRowBtns = document.querySelectorAll('.add-row-btn');
  const cancelBtns = document.querySelectorAll('.edit-form .cancel-btn');
  const messageArea = document.getElementById('message-area');

  // --- Utility Functions ---

  // Display messages (success, error, info)
  function showMessage(type, text) {
      if (!messageArea) return;
      const messageDiv = document.createElement('div');
      messageDiv.className = `message ${type}`;
      messageDiv.textContent = text;
      messageArea.appendChild(messageDiv);
      // Automatically remove the message after some time
      setTimeout(() => {
          messageDiv.remove();
      }, 5000); // Remove after 5 seconds
  }

  // Generic Fetch Wrapper
  async function apiCall(endpoint, method = 'GET', body = null, id = null) {
      const url = id ? `${API_BASE_URL}/${endpoint}?${ENTITY_CONFIG[getEntityTypeFromEndpoint(endpoint)].idField}=${id}` : `${API_BASE_URL}/${endpoint}`;
      const options = {
          method,
          headers: {},
      };
      if (body) {
          options.headers['Content-Type'] = 'application/json';
          options.body = JSON.stringify(body);
      }

      try {
          const response = await fetch(url, options);
          if (!response.ok) {
              const errorData = await response.json().catch(() => ({ error: 'Failed to parse error response' }));
              throw new Error(errorData.error || `HTTP error ${response.status}`);
          }
          // For DELETE requests, often there's no content or just a success message
          if (method === 'DELETE' || response.status === 204) {
              return { success: true };
          }
           // For PUT requests that might return success true or updated data
          const data = await response.json();
          if (method === 'PUT' && data.success === true) {
               return data; // Return success status
          }
          return data; // Return parsed JSON data for GET/POST or PUT with data
      } catch (error) {
          console.error(`API call failed for ${method} ${url}:`, error);
          showMessage('error', `Operation failed: ${error.message}`);
          throw error; // Re-throw to be caught by calling function
      }
  }

   // Helper to get entity type from endpoint filename
  function getEntityTypeFromEndpoint(endpoint) {
      for (const type in ENTITY_CONFIG) {
          if (ENTITY_CONFIG[type].endpoint === endpoint) {
              return type;
          }
      }
      return null;
  }

  // Reset a form and its associated collapse box
  function resetFormAndBox(formId) {
      const form = document.getElementById(formId);
      const box = form.closest('.collapse-box');
      if (form) {
          form.reset();
          form.removeAttribute('data-edit-id');
          // Clear any validation styles if necessary
      }
      if (box) {
          box.classList.remove('open');
      }
  }

  // Populate a select dropdown
  function populateSelect(selectElement, data, valueField, textField, defaultOptionText = '-- Select --', includeIdInText = true) {
      if (!selectElement) return;
      const currentValue = selectElement.value; // Preserve current selection if possible
      // Keep the first option (placeholder) if it exists and is disabled
      const firstOption = selectElement.options[0];
      const keepFirstOption = firstOption && (firstOption.disabled || firstOption.value === "");

      selectElement.innerHTML = ''; // Clear existing options

      if (keepFirstOption) {
          selectElement.appendChild(firstOption.cloneNode(true));
      } else if (defaultOptionText) {
          const defaultOpt = document.createElement('option');
          defaultOpt.value = "";
          defaultOpt.textContent = defaultOptionText;
          defaultOpt.disabled = true;
          defaultOpt.selected = true;
          selectElement.appendChild(defaultOpt);
      }


      data.forEach(item => {
          const option = document.createElement('option');
          option.value = item[valueField];
          option.textContent = includeIdInText
              ? `${item[textField]} (ID: ${item[valueField]})`
              : item[textField];
          selectElement.appendChild(option);
      });

      // Try to restore previous selection
      if (currentValue) {
          selectElement.value = currentValue;
      }
  }

  // --- Dropdown Population Functions ---

  async function populateAllDropdowns() {
      try {
          // Fetch necessary data if not already fetched
          if (departmentsData.length === 0) await fetchAndStoreDepartments();
          if (coursesData.length === 0) await fetchAndStoreCourses();
          if (teachersData.length === 0) await fetchAndStoreTeachers();

          // Populate Department dropdowns
          const deptSelects = document.querySelectorAll('select[name="DepartmentID"]'); // Student, Teacher, Course forms
           deptSelects.forEach(select => {
              // Special handling for Course form's 'Public Course' option
              const isCourseForm = select.id === 'course-department';
              const defaultText = isCourseForm ? null : '-- Select Department --'; // No default needed if Public option exists
              populateSelect(select, departmentsData, 'DepartmentID', 'DepartmentName', defaultText);
              if (isCourseForm) {
                   // Add 'Public Course' option if not already the first one
                  if (!select.options[0] || select.options[0].value !== "") {
                      const publicOption = document.createElement('option');
                      publicOption.value = ""; // Represents NULL
                      publicOption.textContent = "Public Course (No Specific Department)";
                      select.insertBefore(publicOption, select.firstChild);
                      publicOption.selected = true; // Select it by default initially
                  }
              }
          });


          // Populate Course dropdown (in Offering form)
          populateSelect(document.getElementById('offering-course'), coursesData, 'CourseID', 'CourseName', '-- Select Course --');

          // Populate Teacher dropdown (in Offering form)
          populateSelect(document.getElementById('offering-teacher'), teachersData, 'TeacherID', 'Name', '-- Select Teacher --');

      } catch (error) {
          console.error("Failed to populate dropdowns:", error);
          showMessage('error', 'Failed to load data for dropdown menus.');
      }
  }

  // --- Data Fetching and Storage for Dropdowns ---

  async function fetchAndStoreDepartments() {
      departmentsData = await apiCall(ENTITY_CONFIG.department.endpoint);
  }
  async function fetchAndStoreCourses() {
      coursesData = await apiCall(ENTITY_CONFIG.course.endpoint);
  }
  async function fetchAndStoreTeachers() {
      teachersData = await apiCall(ENTITY_CONFIG.teacher.endpoint);
  }


  // --- Rendering Functions ---

  function renderTable(entityType, data) {
      const config = ENTITY_CONFIG[entityType];
      if (!config) return;
      const tableBody = document.getElementById(config.tableBodyId);
      if (!tableBody) return;

      tableBody.innerHTML = ''; // Clear existing rows
      if (!Array.isArray(data) || data.length === 0) {
          tableBody.innerHTML = `<tr><td colspan="100%" style="text-align: center; padding: 20px; color: #777;">No data available.</td></tr>`;
          return;
      }

      data.forEach(item => {
          const row = tableBody.insertRow();
          row.dataset.id = item[config.primaryKey]; // Store ID on the row for easy access

          // Generate cells based on entity type
          let cellsHtml = '';
          switch (entityType) {
              case 'user':
                  cellsHtml = `
                      <td>${item.UserID}</td>
                      <td>${item.Username}</td>
                      <td>${item.Role}</td>
                  `;
                  break;
              case 'student':
                   // Find department name - Requires departmentsData to be loaded
                  const studentDept = departmentsData.find(d => d.DepartmentID == item.DepartmentID);
                  cellsHtml = `
                      <td>${item.StudentID}</td>
                      <td>${item.Name}</td>
                      <td>${item.Gender === 'male' ? '男' : '女'}</td>
                      <td>${studentDept ? `${studentDept.DepartmentName} (${item.DepartmentID})` : `ID: ${item.DepartmentID}`}</td>
                      <td>${item.EnrollmentDate || ''}</td>
                  `;
                  break;
              case 'teacher':
                  const teacherDept = departmentsData.find(d => d.DepartmentID == item.DepartmentID);
                  cellsHtml = `
                      <td>${item.TeacherID}</td>
                      <td>${item.Name}</td>
                      <td>${item.Gender === 'male' ? '男' : '女'}</td>
                      <td>${teacherDept ? `${teacherDept.DepartmentName} (${item.DepartmentID})` : `ID: ${item.DepartmentID}`}</td>
                      <td>${item.Title || ''}</td>
                  `;
                  break;
               case 'department':
                  cellsHtml = `
                      <td>${item.DepartmentID}</td>
                      <td>${item.DepartmentName}</td>
                  `;
                  break;
               case 'course':
                  const courseDept = departmentsData.find(d => d.DepartmentID == item.DepartmentID);
                  cellsHtml = `
                      <td>${item.CourseID}</td>
                      <td>${item.CourseName}</td>
                      <td>${item.Credit}</td>
                      <td>${item.DepartmentID ? (courseDept ? `${courseDept.DepartmentName} (${item.DepartmentID})` : `ID: ${item.DepartmentID}`) : '公共课'}</td>
                      <td>${item.Description || ''}</td>
                  `;
                  break;
               case 'course-offering':
                  const offeringCourse = coursesData.find(c => c.CourseID == item.CourseID);
                  const offeringTeacher = teachersData.find(t => t.TeacherID == item.TeacherID);
                  cellsHtml = `
                      <td>${item.OfferingID}</td>
                      <td>${offeringCourse ? `${offeringCourse.CourseName} (${item.CourseID})` : `CourseID: ${item.CourseID}`}</td>
                      <td>${offeringTeacher ? `${offeringTeacher.Name} (${item.TeacherID})` : `TeacherID: ${item.TeacherID}`}</td>
                      <td>${item.Year}</td>
                      <td>${item.Semester === 'spring' ? '春季' : '秋季'}</td>
                      <td>${item.Capacity}</td>
                  `;
                  break;
              // Add 'enrollment' case if needed
          }

          // Add action buttons cell
          cellsHtml += `
              <td class="action-buttons">
                  <button class="icon-button edit-button" data-id="${item[config.primaryKey]}" title="编辑"><i class="fas fa-edit"></i></button>
                  <button class="icon-button delete-button" data-id="${item[config.primaryKey]}" title="删除"><i class="fas fa-trash"></i></button>
              </td>
          `;
          row.innerHTML = cellsHtml;
      });
  }

  // --- Fetch and Render Data ---
  async function loadData(entityType) {
      const config = ENTITY_CONFIG[entityType];
      if (!config) return;
      const tableBody = document.getElementById(config.tableBodyId);
      if(tableBody) tableBody.classList.add('loading'); // Add loading state

      try {
          // Ensure dropdown data is ready before rendering tables that need it
           if (entityType === 'student' || entityType === 'teacher' || entityType === 'course') {
              if (departmentsData.length === 0) await fetchAndStoreDepartments();
          }
          if (entityType === 'course-offering') {
              if (coursesData.length === 0) await fetchAndStoreCourses();
              if (teachersData.length === 0) await fetchAndStoreTeachers();
          }

          const data = await apiCall(config.endpoint);
          renderTable(entityType, data);
      } catch (error) {
          console.error(`Failed to load data for ${entityType}:`, error);
           if(tableBody) tableBody.innerHTML = `<tr><td colspan="100%" style="text-align: center; padding: 20px; color: #e74c3c;">Error loading data.</td></tr>`;
      } finally {
           if(tableBody) tableBody.classList.remove('loading'); // Remove loading state
      }
  }


  // --- Event Handlers ---

  // Tab Switching
  sidebarMenuItems.forEach(item => {
      item.addEventListener('click', () => {
          sidebarMenuItems.forEach(i => i.classList.remove('active'));
          tabContents.forEach(tc => tc.classList.remove('active'));

          item.classList.add('active');
          const targetTabId = item.getAttribute('data-tab');
          const targetTabContent = document.getElementById(targetTabId);
          if (targetTabContent) {
              targetTabContent.classList.add('active');
              // Load data for the activated tab if it hasn't been loaded yet
              // Or simply reload data every time tab is switched (simpler for now)
              const entityType = targetTabId.replace('-management', '');
              if (ENTITY_CONFIG[entityType]) {
                  loadData(entityType);
              }
          }
           // Close any open forms when switching tabs
          document.querySelectorAll('.collapse-box.open').forEach(box => {
              const form = box.querySelector('form');
              resetFormAndBox(form.id);
          });
      });
  });

  // "Add New" Button Click
  addRowBtns.forEach(btn => {
      btn.addEventListener('click', () => {
          const formBoxId = btn.getAttribute('data-form-box');
          const formBox = document.getElementById(formBoxId);
          const form = formBox.querySelector('form');

           // Reset form before opening for 'Add'
          resetFormAndBox(form.id); // Ensures no edit ID is present

          // Special handling for student/teacher add forms (enable username/password)
          if (form.id === 'add-student-form' || form.id === 'add-teacher-form') {
              form.querySelector('input[name="Username"]').disabled = false;
              form.querySelector('input[name="Password"]').disabled = false;
              form.querySelector('input[name="Password"]').required = true; // Make password required for add
          }
           // Special handling for user form (make password required for add)
          if (form.id === 'add-user-form') {
              form.querySelector('input[name="Password"]').required = true;
               form.querySelector('input[name="Username"]').disabled = false; // Ensure username is editable for add
          }

          formBox.classList.toggle('open');
           if (formBox.classList.contains('open')) {
              form.querySelector('input, select, textarea')?.focus();
          }
      });
  });

  // Cancel Button Click
  cancelBtns.forEach(btn => {
      btn.addEventListener('click', () => {
          const form = btn.closest('form');
          resetFormAndBox(form.id);
      });
  });

  // Form Submission (Add & Edit)
  document.querySelectorAll('.edit-form').forEach(form => {
      form.addEventListener('submit', async (event) => {
          event.preventDefault();
          const entityType = form.id.replace('add-', '').replace('-form', '');
          const config = ENTITY_CONFIG[entityType];
          if (!config) return;

          const editId = form.dataset.editId;
          const method = editId ? 'PUT' : 'POST';
          const formData = new FormData(form);
          const data = Object.fromEntries(formData.entries());

          // Adjust data before sending
           // Handle checkbox/radio if needed
           // Convert empty strings for nullable foreign keys/numbers to null
          Object.keys(data).forEach(key => {
              if (key.includes('ID') && data[key] === "") { // Like DepartmentID in Course form
                 data[key] = null;
              }
              if(key === 'Credit' || key === 'Capacity' || key === 'Year') {
                  if(data[key] === "") data[key] = null; // Or handle validation earlier
              }
               // Don't send password if editing and field is empty
               if(key === 'Password' && method === 'PUT' && data[key] === '') {
                  delete data[key];
               }
               // Remove username/password fields if editing student/teacher (handled by User management)
               if(method === 'PUT' && (form.id === 'add-student-form' || form.id === 'add-teacher-form')) {
                   delete data['Username'];
                   delete data['Password'];
               }
                // Remove UserID from Student/Teacher data (it's the primary key)
               if((entityType === 'student' && key === 'UserID') || (entityType === 'teacher' && key === 'UserID')) {
                  delete data[key];
               }
          });


          try {
              if (method === 'POST') {
                  await apiCall(config.endpoint, 'POST', data);
                  showMessage('success', `${config.nameField || 'Record'} added successfully!`);
              } else {
                  await apiCall(config.endpoint, 'PUT', data, editId);
                   showMessage('success', `${config.nameField || 'Record'} (ID: ${editId}) updated successfully!`);
              }
              resetFormAndBox(form.id);
              loadData(entityType); // Refresh table
              // Refresh dropdown data if a relevant entity was changed
              if(entityType === 'department') await fetchAndStoreDepartments().then(populateAllDropdowns);
              if(entityType === 'course') await fetchAndStoreCourses().then(populateAllDropdowns);
              if(entityType === 'teacher') await fetchAndStoreTeachers().then(populateAllDropdowns);

          } catch (error) {
              // Error message already shown by apiCall
              console.error("Form submission error:", error);
          }
      });
  });

  // Table Action Buttons (Edit & Delete) - Event Delegation
  document.querySelectorAll('.data-table tbody').forEach(tbody => {
      tbody.addEventListener('click', async (event) => {
          const editButton = event.target.closest('.edit-button');
          const deleteButton = event.target.closest('.delete-button');
          const entityType = tbody.id.replace('-table-body', '');
          const config = ENTITY_CONFIG[entityType];

          if (!config) return;

          // --- Edit Action ---
          if (editButton) {
              const id = editButton.dataset.id;
              const form = document.getElementById(config.formId);
              const box = form.closest('.collapse-box');

              // Reset form before populating for edit
              resetFormAndBox(form.id);

              try {
                  // Fetch the specific record data for accurate population
                  // Note: API must support fetching single record by ID for this to work best
                  // Fallback: Use data from the table row if single fetch fails/not implemented
                  // let itemData = await apiCall(config.endpoint, 'GET', null, id); // Ideal
                  // Fallback implementation (using row data - less reliable for complex fields):
                  const row = editButton.closest('tr');
                  const itemData = {};
                  const inputs = form.querySelectorAll('input, select, textarea');
                  inputs.forEach(input => {
                       const key = input.name;
                       if (!key || key === 'Password' || key === 'Username') return; // Don't fetch password/username from row
                       // Find corresponding cell - This is brittle, relies on order
                       const cellIndex = Array.from(row.parentNode.rows[0].cells).findIndex(th => th.textContent.toLowerCase().includes(key.toLowerCase().replace('id','')));
                       // A better way is to store all data in row.dataset or fetch single item
                       // For simplicity now, we'll just populate known fields directly if fetch fails

                       // Find the cell based on header text or a predefined map
                      const headerText = Array.from(row.closest('table').querySelectorAll('thead th'))
                                           .find(th => th.dataset.fieldName === key)?.textContent;
                      // THIS PART IS DIFFICULT WITHOUT SINGLE ITEM FETCH OR DATA ATTRIBUTES ON ROW
                      // We will populate manually based on common fields for now

                  });

                   // Populate form - Manual based on common field names
                   const fetchedItem = await apiCall(config.endpoint, 'GET', null, id); // Try fetching the single item
                   if(fetchedItem) {
                       Object.keys(fetchedItem).forEach(key => {
                           const input = form.querySelector(`[name="${key}"]`);
                           if (input) {
                               if (input.type === 'date') {
                                   input.value = fetchedItem[key] ? fetchedItem[key].split('T')[0] : ''; // Format date YYYY-MM-DD
                               } else {
                                   input.value = fetchedItem[key] ?? ''; // Use nullish coalescing for null/undefined
                               }
                           }
                       });
                   } else {
                       showMessage('warning', 'Could not fetch full record details for editing. Populating from table.');
                       // Populate manually from known fields (example for student)
                       if(entityType === 'student') {
                            form.querySelector('[name="Name"]').value = row.cells[1].textContent;
                            form.querySelector('[name="Gender"]').value = row.cells[2].textContent === '男' ? 'male' : 'female';
                            // Getting DepartmentID correctly requires it stored on the row/button or fetched
                            // form.querySelector('[name="DepartmentID"]').value = ???;
                            form.querySelector('[name="EnrollmentDate"]').value = row.cells[4].textContent;
                       }
                       // Add similar fallback population for other entities if needed
                   }


                  form.dataset.editId = id; // Set the edit ID

                   // Special handling for student/teacher edit forms (disable username/password)
                  if (form.id === 'add-student-form' || form.id === 'add-teacher-form') {
                      form.querySelector('input[name="Username"]').disabled = true;
                      form.querySelector('input[name="Password"]').disabled = true;
                      form.querySelector('input[name="Password"]').required = false; // Pwd not required for edit unless changing
                       form.querySelector('input[name="Password"]').placeholder = "留空则不修改密码";
                  }
                   // Special handling for user form edit
                   if(form.id === 'add-user-form') {
                        form.querySelector('input[name="Password"]').required = false;
                        form.querySelector('input[name="Password"]').placeholder = "留空则不修改密码";
                        form.querySelector('input[name="Username"]').disabled = true; // Usually username is not editable
                   }


                  box.classList.add('open');
                  form.querySelector('input, select, textarea')?.focus();

              } catch (error) {
                  showMessage('error', `Failed to prepare edit form: ${error.message}`);
              }
          }

          // --- Delete Action ---
          if (deleteButton) {
              const id = deleteButton.dataset.id;
              const recordName = deleteButton.closest('tr')?.cells[1]?.textContent || `ID ${id}`; // Get a name/identifier for confirmation

              if (confirm(`确定要删除 ${config.nameField || 'record'} "${recordName}" (ID: ${id}) 吗？`)) {
                  try {
                      await apiCall(config.endpoint, 'DELETE', null, id);
                      showMessage('success', `${config.nameField || 'Record'} (ID: ${id}) deleted successfully!`);
                      loadData(entityType); // Refresh table
                      // Refresh dropdown data if a relevant entity was deleted
                      if(entityType === 'department') await fetchAndStoreDepartments().then(populateAllDropdowns);
                      if(entityType === 'course') await fetchAndStoreCourses().then(populateAllDropdowns);
                      if(entityType === 'teacher') await fetchAndStoreTeachers().then(populateAllDropdowns);
                  } catch (error) {
                      // Error message already shown by apiCall
                       console.error("Deletion error:", error);
                  }
              }
          }
      });
  });


  // --- Initial Load ---
  async function initializeApp() {
      // Load data needed for dropdowns first
      await populateAllDropdowns();

      // Load data for the initially active tab
      const activeTab = document.querySelector('.sidebar-menu li.active');
      if (activeTab) {
          const initialEntityType = activeTab.getAttribute('data-tab').replace('-management', '');
          if (ENTITY_CONFIG[initialEntityType]) {
              loadData(initialEntityType);
          }
      } else {
          // Fallback: load user data if no tab is active initially (shouldn't happen with default active)
          loadData('user');
      }
       // Add Search functionality listeners if needed here
       // setupSearchListeners();
  }

  initializeApp();

}); // End DOMContentLoaded